/* * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package main.java.com.amazonaws.cognito.devauthsample; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; /** * A utility class to encrypt and decrypt strings. */ public class AESEncryption { /** * Encryption algorithm */ public static final String ENCRYPTION_ALGORITHM = "AES/CBC/PKCS5Padding"; /** * Encrypt a string with a given key. * * @param clearText * string to be encrypted * @param key * encryption key * @return encrypted string */ public static String wrap(String clearText, String key) { byte[] iv = getIv(); byte[] cipherText = encrypt(clearText, key, iv); byte[] wrapped = new byte[iv.length + cipherText.length]; System.arraycopy(iv, 0, wrapped, 0, iv.length); System.arraycopy(cipherText, 0, wrapped, 16, cipherText.length); return new String(Base64.encodeBase64(wrapped)); } /** * Decrypt a string with given key. * * @param cipherText * encrypted string * @param key * the key used in decryption * @return a decrypted string */ public static String unwrap(String cipherText, String key) { byte[] dataToDecrypt = Base64.decodeBase64(cipherText.getBytes()); byte[] iv = new byte[16]; byte[] data = new byte[dataToDecrypt.length - 16]; System.arraycopy(dataToDecrypt, 0, iv, 0, 16); System.arraycopy(dataToDecrypt, 16, data, 0, dataToDecrypt.length - 16); byte[] plainText = decrypt(data, key, iv); return new String(plainText); } private static byte[] encrypt(String clearText, String key, byte[] iv) { try { Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM); AlgorithmParameters params = AlgorithmParameters.getInstance("AES"); params.init(new IvParameterSpec(iv)); cipher.init(Cipher.ENCRYPT_MODE, getKey(key), params); return cipher.doFinal(clearText.getBytes()); } catch (GeneralSecurityException e) { throw new RuntimeException("Failed to encrypt.", e); } } private static byte[] decrypt(byte[] cipherBytes, String key, byte[] iv) { try { Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM); AlgorithmParameters params = AlgorithmParameters.getInstance("AES"); params.init(new IvParameterSpec(iv)); cipher.init(Cipher.DECRYPT_MODE, getKey(key), params); return cipher.doFinal(cipherBytes); } catch (GeneralSecurityException e) { throw new RuntimeException("Failed to decrypt.", e); } } private static SecretKeySpec getKey(String key) { try { return new SecretKeySpec(Hex.decodeHex(key.toCharArray()), "AES"); } catch (DecoderException e) { throw new RuntimeException("Failed to generate a secret key spec", e); } } private static byte[] getIv() { byte[] iv = new byte[16]; new SecureRandom().nextBytes(iv); return iv; } }